// PanelSelect.cpp

#include "StdAfx.h"

#include "Panel.h"

#include "Common/FileSystem/Wildcard.h"


#include "ComboDialog.h"

#include "Common/Lang/LangUtils.h"

using namespace Common;

LRESULT CPanel::OnShiftSelectMessage(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL & /*bHandled*/)
{
	if (!_mySelectMode)
	{
		return 0;
	}
	int focusedItem = _listView.GetNextItem(-1, LVNI_FOCUSED);
	if (focusedItem < 0)
	{
		return 0;
	}
	if (!_selectionIsDefined)
	{
		return 0;
	}
	int startItem = min(focusedItem, _prevFocusedItem);
	int finishItem = max(focusedItem, _prevFocusedItem);
	for (int i = 0; i < _listView.GetItemCount(); i++)
	{
		int realIndex = GetRealItemIndex(i);
		if (realIndex == FileManager::FileSystem::kParentIndex)
		{
			continue;
		}
		if (i >= startItem && i <= finishItem)
			if (_selectedStatusVector[realIndex] != _selectMark)
			{
				_selectedStatusVector[realIndex] = _selectMark;
				_listView.RedrawItems(i, i);
			}
	}
	_prevFocusedItem = focusedItem;
	return 0;
}

void CPanel::OnArrowWithShift()
{
	if (!_mySelectMode)
	{
		return;
	}
	int focusedItem = _listView.GetNextItem(-1, LVNI_FOCUSED);
	if (focusedItem < 0)
	{
		return;
	}
	int realIndex = GetRealItemIndex(focusedItem);
	if (_selectionIsDefined)
	{
		if (realIndex != FileManager::FileSystem::kParentIndex)
		{
			_selectedStatusVector[realIndex] = _selectMark;
		}
	}
	else
	{
		if (realIndex == FileManager::FileSystem::kParentIndex)
		{
			_selectionIsDefined = true;
			_selectMark = true;
		}
		else
		{
			_selectionIsDefined = true;
			_selectMark = !_selectedStatusVector[realIndex];
			_selectedStatusVector[realIndex] = _selectMark;
		}
	}
	_prevFocusedItem = focusedItem;
	PostMessage(kShiftSelectMessage);
	_listView.RedrawItems(focusedItem, focusedItem);
}

void CPanel::OnInsert()
{
	int focusedItem = _listView.GetNextItem(-1, LVNI_FOCUSED);
	if (focusedItem < 0)
	{
		return;
	}
	int realIndex = GetRealItemIndex(focusedItem);
	bool isSelected = !_selectedStatusVector[realIndex];
	if (realIndex != FileManager::FileSystem::kParentIndex)
	{
		_selectedStatusVector[realIndex] = isSelected;
	}

	if (!_mySelectMode)
	{
		_listView.SetItemState(focusedItem, isSelected ? LVIS_SELECTED : 0, LVIS_SELECTED);
	}

	_listView.RedrawItems(focusedItem, focusedItem);

	int nextIndex = focusedItem + 1;
	if (nextIndex < _listView.GetItemCount())
	{
		_listView.SetItemState(nextIndex, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED);
		_listView.EnsureVisible(nextIndex, false);
	}
}

void CPanel::UpdateSelection()
{
	if (!_mySelectMode)
	{
		bool enableTemp = _enableItemChangeNotify;
		_enableItemChangeNotify = false;
		int numItems = _listView.GetItemCount();
		for (int i = 0; i < numItems; i++)
		{
			int realIndex = GetRealItemIndex(i);
			if (realIndex != FileManager::FileSystem::kParentIndex)
			{
				UINT value = 0;
				value = _selectedStatusVector[realIndex] ? LVIS_SELECTED : 0;
				_listView.SetItemState(i, value, LVIS_SELECTED);
			}
		}
		_enableItemChangeNotify = enableTemp;
	}
	if (_listView.GetItemCount() > 0)
	{
		_listView.RedrawItems(0, _listView.GetItemCount() - 1);
	}

}


void CPanel::SelectSpec(bool selectMode)
{
	CComboDialog comboDialog;
	comboDialog.Title = selectMode ?
						Lang::LangString(IDS_SELECT, 0x03020250) :
						Lang::LangString(IDS_DESELECT, 0x03020251);
	comboDialog.Static = Lang::LangString(IDS_SELECT_MASK, 0x03020252);
	comboDialog.Value = _T("*");
	if (comboDialog.DoModal() == IDCANCEL)
	{
		return;
	}
	const CString &mask = comboDialog.Value;
	for (size_t i = 0; i < _selectedStatusVector.size(); i++)
		if (Common::FileSystem::CompareWildCardWithName(mask, m_directory.GetItemName(i)))
		{
			_selectedStatusVector[i] = selectMode;
		}
	UpdateSelection();
}

void CPanel::SelectByType(bool selectMode)
{
	int focusedItem = _listView.GetNextItem(-1, LVNI_FOCUSED);
	if (focusedItem < 0)
	{
		return;
	}
	int realIndex = GetRealItemIndex(focusedItem);
	m_directory.SelectByType(realIndex, _selectedStatusVector, selectMode);
	UpdateSelection();
}

void CPanel::SelectAll(bool selectMode)
{
	for (size_t  i = 0; i < _selectedStatusVector.size(); i++)
	{
		_selectedStatusVector[i] = selectMode;
	}
	UpdateSelection();
}

void CPanel::InvertSelection()
{
	if (!_mySelectMode)
	{
		int numSelected = 0;
		for (size_t  i = 0; i < _selectedStatusVector.size(); i++)
			if (_selectedStatusVector[i])
			{
				numSelected++;
			}
		if (numSelected == 1)
		{
			int focused = _listView.GetNextItem(-1, LVNI_FOCUSED);
			if (focused >= 0)
			{
				int realIndex = GetRealItemIndex(focused);
				if (realIndex >= 0)
					if (_selectedStatusVector[realIndex])
					{
						_selectedStatusVector[realIndex] = false;
					}
			}
		}
	}
	for (size_t  i = 0; i < _selectedStatusVector.size(); i++)
	{
		_selectedStatusVector[i] = !_selectedStatusVector[i];
	}
	UpdateSelection();
}

void CPanel::KillSelection()
{
	SelectAll(false);
	if (!_mySelectMode)
	{
		int focused = _listView.GetNextItem(-1, LVNI_FOCUSED);
		if (focused >= 0)
		{
			// CPanel::OnItemChanged notify for LVIS_SELECTED change doesn't work here. Why?
			// so we change _selectedStatusVector[realIndex] here.
			int realIndex = GetRealItemIndex(focused);
			if (realIndex != FileManager::FileSystem::kParentIndex)
			{
				_selectedStatusVector[realIndex] = true;
			}
			_listView.SetItemState(focused, LVIS_SELECTED, LVIS_SELECTED);
		}
	}
}

void CPanel::OnLeftClick(MY_NMLISTVIEW_NMITEMACTIVATE* itemActivate)
{
	if (itemActivate->hdr.hwndFrom != HWND(_listView))
	{
		return;
	}
	// It will be work only for Version 4.71 (IE 4);
	int indexInList = itemActivate->iItem;
	if (indexInList < 0)
	{
		return;
	}
#ifndef UNDER_CE
	if ((itemActivate->uKeyFlags & LVKF_SHIFT) != 0)
	{
		int focusedIndex = _startGroupSelect;
		if (focusedIndex < 0)
		{
			return;
		}
		int startItem = min(focusedIndex, indexInList);
		int finishItem = max(focusedIndex, indexInList);
		for (BoolVector::size_type i = 0; i < _selectedStatusVector.size(); i++)
		{
			int realIndex = GetRealItemIndex(i);
			if (realIndex == FileManager::FileSystem::kParentIndex)
			{
				continue;
			}
			bool selected = (i >= startItem && i <= finishItem);
			if (_selectedStatusVector[realIndex] != selected)
			{
				_selectedStatusVector[realIndex] = selected;
				_listView.RedrawItems(i, i);
			}
		}
	}
	else
#endif
	{
		_startGroupSelect = indexInList;
#ifndef UNDER_CE
		if ((itemActivate->uKeyFlags & LVKF_CONTROL) != 0)
		{
			int realIndex = GetRealItemIndex(indexInList);
			if (realIndex != FileManager::FileSystem::kParentIndex)
			{
				_selectedStatusVector[realIndex] = !_selectedStatusVector[realIndex];
				_listView.RedrawItems(indexInList, indexInList);
			}
		}
#endif
	}
	return;
}
